import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:amap_location_fluttify/amap_location_fluttify.dart';
import 'package:flutter/material.dart';
import 'package:C20Driver/config/service_api.dart';
import 'package:C20Driver/event/event_bus.dart';
import 'package:C20Driver/model/mqtt_message_location.dart';
import 'package:C20Driver/model/mqtt_msg_model.dart';
import 'package:C20Driver/provider/driver_information.dart';
import 'package:C20Driver/provider/order_information.dart';
import 'package:C20Driver/provider/position_information.dart';
import 'package:C20Driver/resources/app_storage_interface.dart';
import 'package:C20Driver/service/request.dart';
import 'package:C20Driver/utils/order_monitoring.dart';
import 'package:C20Driver/utils/permission_handler.dart';
import 'package:C20Driver/utils/toast.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

final _client = MqttServerClient(ServiceApi.socketUrl, '');
String _token;
String _userId;
BuildContext _context;
String _clientId;
MqttMsgModel _model;
bool _isDisconnect; //是否主动断开连接（是 无需重连）
Timer _timer;
var _timerMqtt;

class MqttManage {
  static MqttManage _instance;

  static MqttManage getInstance() {
    if (_instance == null) {
      print("测试mqtt2");

      _instance = MqttManage();
    }
    return _instance;
  }

  /// 获取Token
  static Future _getToken() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _token = prefs.getString(AppStorageInterface.LOGINTOKEN); // 获取存储的token
  }

  /// 初始化配置mqtt
  Future<int> init(String userId, BuildContext context) async {
    /// 检查连接状态
    if (_client.connectionStatus.state == MqttConnectionState.connected ||
        _client.connectionStatus.state == MqttConnectionState.connecting) {
      print('EXAMPLE::已连接Mosquito客户端');
      return 1;
    }

    _userId = userId;
    _context = context;
    _clientId = '${userId}_driver_app_mtsl';
    _isDisconnect = false;
    await _getToken();
    print('_token========================');
    print(_token);

    /// 日志
    _client.logging(on: false);

    /// 超时时间s  默认为60s
    _client.keepAlivePeriod = 20;

    /// 连接成功回调
    _client.onConnected = onConnected;

    /// 连接断开回调
    _client.onDisconnected = onDisconnected;

    /// 订阅成功回调
    _client.onSubscribed = onSubscribed;

    _client.pongCallback = ping;

    final connMess = MqttConnectMessage()
        .withClientIdentifier(_clientId)
        .authenticateAs('driver_$userId', _token)
        .keepAliveFor(20) // Must agree with the keep alive set above or not set
        .withWillTopic(
            'willtopic') // If you set this you must set a will message
        .withWillMessage('My Will message')
        .startClean() // Non persistent session for testing
        .withWillQos(MqttQos.atLeastOnce);
    print('EXAMPLE::Mosquitto client connecting....');
    _client.connectionMessage = connMess;

    try {
      await _client.connect();
    } on Exception catch (e) {
      print('MqttUtils::client exception - $e');
      _client.disconnect();
    }

    /// 检查连接状态
    if (_client.connectionStatus.state == MqttConnectionState.connected) {
      print('EXAMPLE::已连接Mosquito客户端');
    } else {
      print(
          'EXAMPLE::错误mosquito客户端连接失败-正在断开连接，状态为 ${_client.connectionStatus.state}');
      // _client.disconnect();
      // exit(-1);
    }

    // 监听订阅消息的响应
    _client.updates.listen((dynamic c) {
      final MqttPublishMessage recMess = c[0].payload;

      ///服务器返回的数据信息
      _model = MqttMsgModel.fromJson(
          jsonDecode(Utf8Decoder().convert(recMess.payload.message)));
      print(
          '111111111111111111:: topic is <${c[0].topic}>, payload is <-- ${jsonDecode(Utf8Decoder().convert(recMess.payload.message))} -->');
      if (c[0].topic == 'mtsl/SYSTEM') {
      } else if (c[0].topic == 'mtsl/PRIVATE/$_clientId') {
        if (_model.messageType == 'NotifAppAction') {
        } else if (_model.messageType == 'NotificationOrder') {
          if (_model.content['type'] == '0020' ||
              _model.content['type'] == '0022') {
            // 正常派单
            // print('444444444444444444444--${_model.toString()}');
            OrderMonitoring().getAppOrderMonitoring(_context, _model.content);
          } else if (_model.content['type'] == '0033') {
            showDialog(
              context: _context,
              builder: (context) => AlertDialog(
                title: Text('用户取消订单'),
                actions: <Widget>[
                  FlatButton(
                    child: Text('确定'),
                    onPressed: () {
                      Navigator.pop(_context);
                      eventBus.fire(new SetDispatchOrderList());
                      Navigator.of(context)
                          .popUntil(ModalRoute.withName("/indexPage"));
                    },
                  ),
                ],
              ),
            );
          } else if (_model.content['type'] == '1000') {
            if (_model.content['order_type'] == 'driverfee') {
              // 司机认证费
              ToastX.center("支付成功");
              Request.certificatonAudit(_context);
            }
          }
        } else if (_model.messageType == 'Location') {}
      }
    });

    _client.published.listen((MqttPublishMessage message) {
      print(
          'MqttUtils::Published notification:: topic is ${message.variableHeader.topicName}, with Qos ${message.header.qos}');
    });

    return 0;
  }

  /// 订阅消息
  bool subscribe(String topic,
      {MqttQos qosLevel = MqttQos.atMostOnce, Function callBack}) {
    // 订阅
    _client.subscribe(topic, qosLevel);
    return true;
  }

  /// 取消订阅
  bool unsubscribe(String topic) {
    print('MqttUtils::Unsubscribing' + topic);
    _client.unsubscribe(topic);
    return true;
  }

  /// 中断连接
  void disconnect() {
    _isDisconnect = true;
    print('MqttUtils::Disconnecting');
    _client.disconnect();
    _client.securityContext = null;
  }

  bool isConnected() {
    // return _connected;
  }

  /// 发送消息  qualityOfService：对应接口文档的 qos 参数
  void publishMessage(String topic, String jsonString, {Function callBack}) {
    print("发送消息  qualityOfService：对应接口文档的 qos 参数");
    print(topic);
    print(jsonString);
    final builder1 = MqttClientPayloadBuilder();
    builder1.addString(jsonString);
    print('EXAMPLE:: <<<< PUBLISH 1 >>>>');
    _client.publishMessage(topic, MqttQos.atLeastOnce, builder1.payload);
    // callBack(jsonString);
  }

  /// 司机出车
  /// value: on 出车,off 收车
  Future<bool> driverOnline(BuildContext context, String value) async {
    DriverInformation driverInformation =
        Provider.of<DriverInformation>(_context, listen: false);
    // var driver =
    //     Provider.of<DriverInformation>(context, listen: false).driverJson;
    PositionInformation position =
        Provider.of<PositionInformation>(context, listen: false);
    String lonlat = '';
    if (position.driverLocation != null) {
      lonlat = position.driverLocation.longitude.toString() +
          ',' +
          position.driverLocation.latitude.toString();
    } else {
      var location =
          await AmapLocation.fetchLocation(mode: LocationAccuracy.High);
      lonlat = location.latLng.longitude.toString() +
          ',' +
          location.latLng.latitude.toString();
    }
    //on 打开接收,off 关闭接收,
    String time = DateTime.now().millisecondsSinceEpoch.toString();
    MqttMsgModel model = MqttMsgModel(
      messageType: 'NotifAppAction',
      targetId: 'SYSTEM',
      sendId: _clientId,
      sendTimeStamp: time,
      content: {
        'type': 'order',
        'action': 'acceptOrder',
        'value': value,
        'lonlat': lonlat,
        'driverInfo': '123123',
      },
    );
    print('sendNotifAppAction${jsonEncode(model)}');

    publishMessage('mtsl/LOCATION/$_clientId', jsonEncode(model));
    driverInformation.setDriverInformation(workingStatus: '0020');
    return true;
  }

  /// 持续发送司机当前定位
  Future<void> continuousSendLocation(BuildContext context) async {
    if (_timer != null) {
      _timer.cancel();
    }
    if (await PermissionHandlerX.position(_context)) {
      // final location = await AmapLocation.fetchLocation(mode: LocationAccuracy.High);
      // Provider.of<PositionInformation>(_context, listen: false)
      //     .setRealtimeDriverPosition(_context, location.latLng.latitude,
      //         location.latLng.longitude, _userId);
      _timer = Timer.periodic(Duration(seconds: 30), (timer) async {
        print("持续发送司机当前定位==============>>>>>>>>>>>");
        final location =
            await AmapLocation.fetchLocation(mode: LocationAccuracy.High);
        // AmapLocation.dispose();
        // 实时发送位置
        OrderInformation providerOrder =
            Provider.of<OrderInformation>(_context, listen: false);
        String _isOrder = '';
        String _orderId = '';
        if (providerOrder.itineraryInfo != null) {
          if (providerOrder.itineraryInfo.orderId != null) {
            _isOrder = "1";
            _orderId = providerOrder.itineraryInfo.orderId;
          } else {
            _isOrder = "0";
          }
        }

        MqttMessageLocation mqttMessageLocation = MqttMessageLocation(
            messageType: 'Location',
            targetId: 'targetId',
            sendId: _clientId,
            sendTimeStamp: DateTime.now().millisecondsSinceEpoch.toString(),
            content: {
              'currentLongitude': location.latLng.longitude.toString(),
              'currentLatitude': location.latLng.latitude.toString(),
              'isOrderLocation': _isOrder,
              'orderId': _orderId,
            });
        publishMessage(
            'mtsl/LOCATION/$_clientId', jsonEncode(mqttMessageLocation));
        Provider.of<PositionInformation>(_context, listen: false)
            .setRealtimeDriverPosition(_context, location.latLng.latitude,
                location.latLng.longitude, _userId);
      });
    }
  }

  void setContext(BuildContext context) {
    _context = context;
  }

  String get getClientId => _clientId;
}

/// 连接成功的回调
void onConnected() {
  print(
      'MqttUtils::OnConnected client callback - Client connection was sucessful');
  // testtopic1  ==> 订阅名称
  /// 订阅系统消息
  MqttManage.getInstance().subscribe('mtsl/SYSTEM', callBack: (e) {});

  /// 订阅所有司机的
  MqttManage.getInstance().subscribe('mtsl/GROUP/DRIVERS', callBack: (e) {});

  /// 订阅司机自己专有频道
  MqttManage.getInstance()
      .subscribe('mtsl/PRIVATE/${_userId}_driver_app_mtsl', callBack: (e) {});

  _timerMqtt?.cancel();
  _timerMqtt = null;
}

void onSubscribed(String topic) {
  print('已确认订阅主题 $topic');
  if (topic == "mtsl/PRIVATE/${_userId}_driver_app_mtsl") {
    print("订阅司机自己专有频道-----------=========");
    MqttManage().continuousSendLocation(_context);
  }
}

/// The unsolicited disconnect callback
void onDisconnected() {
  print('-客户端断开连接');
  print('MqttUtils::OnDisconnected client callback - Client disconnection');
  // if (_client.connectionStatus.returnCode == MqttConnectReturnCode.solicited) {
  //   print('MqttUtils::OnDisconnected callback is solicited, this is correct');
  // }
  // ToastX.center('客户端断开连接');
  if (_timer != null) {
    _timer.cancel();
    _timer = null;
  }
  if (!_isDisconnect) {
    //尝试自动重连
    tryReconnection(true);
    //收集断线后定位信息
    // getLocationList();
  }
}

void tryReconnection(bool onTime) {
  if (onTime) {
    if (_timerMqtt == null) {
      _timerMqtt = new Timer.periodic(new Duration(seconds: 20), (timer) async {
        _client.connect();
      });
    }
  } else {
    _timerMqtt?.cancel();
    _timerMqtt = null;
  }
}

void ping() {
  print('MqttUtils::Ping response client callback invoked');
}
